[toc]
python基础二十六 网络编程-udp编程
1.Socket编程简介
1.1 含义
socket:套接字,通过网路完成进程间通信的方式(区别于一台计算机之间进程通信)
1.2 说明
-
socket本质是
编程接口(API)
:socket是对TCP/IP协议的封装,socket只是个编程接口不是协议,通过socket我们才能使用TCP/IP协议簇 -
TCP/IP也要提供可供程序员做网络开发所用的接口,这就是socket编程接口,socket提供了网络通信的能力
-
套接字之间的连接过程可分为3个步骤:
- 1.服务器监听
- 2.客户端请求
- 3.连接确认
2.创建socket
语法
#导入套接字模块
from socket import *
#创建套接字对象
s = socket(socket.AF_NENT,SOCK_DGRAM)
参数说明
AF_NENT #指明IPV4
SOCKET_DGRAM #套接字类型,SOCKET_DGRAM是tcp协议
SOCKET_STREAM #套接字类型,SOCKET_STREAM是udp协议
3.socket编程-udp
3.1 udp说明
3.1.1 概念
UDP:User Data Protocol,用户数据报协议,是一个无连接的简单的面向数据报的传输层协议,udp不提供可靠性,它只是把应用层传给IP层的数据报发出去,但是并不能保证它们能到达目的地,由于udp在传输数据报前不用在客户端和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快
3.1.2 udp用处
udp一般用于多点通信和实时的数据业务,比如
- 语音广播
- 视频
- TFTP(简单文件传输)
3.2 使用udp发送数据
第一步
发送数据,为看到效果先安装网络调试助手NetAssist(windows安装)
NetAssist初始配置,协议选择UDP,IP地址会自动识别本机地址,端口号任意选择一个可使用的,配置完成后点击连接
按钮
from socket import *
#AF_INET表示IPV4 SOCK_DGRAM表示udp协议
s = socket(AF_INET,SOCK_DGRAM)
#NetAssist中的默认编码是gb2312,这里需要指定一下,否则显示的信息会是乱码
s.sendto("你好".encode("gb2312"),("192.168.34.90",8080))
第二步
运行以上代码,会在NetAssist中看到效果
这里可以看到发送的你好已经在NetAssist中收到
3.3 使用udp接收数据
3.3.1 udp接收数据
from socket import *
s = socket(AF_INET, SOCK_DGRAM) #创建套接字
addr = ('127.0.0.1', 8888) #准备接收方地址
data = input("请输入:")
s.sendto(data.encode(),addr) #等待接收数据
redata = s.recvfrom(1024) #1024表示本次接收的最大字节数
print(redata)
s.close()
mac和linux中运行程序,输入内容后程序会卡住,原因未知⚠️⚠️⚠️
windows中运行程序,输入内容后会返回如下结果
(b'abc', ('127.0.0.1', 8888))
3.2.2 udp绑定信息 bind
如果信息(IP地址、端口号)没有绑定,每发送一次信息,系统会随机分配一个端口,还要避免同一台计算机上的不同进程端口号相同的问题
绑定信息:让一个进程可以使用固定的端口
一般情况下,发送方不绑定端口,接收方会绑定
from socket import *
s = socket(AF_INET, SOCK_DGRAM) #创建套接字
s.bind(('', 8788)) #绑定本机一个端口,ip地址和端⼝号,ip⼀般不⽤写
addr = ('192.168.1.17', 8080) #准备接收方地址和端口
data = input("请输入:")
s.sendto(data.encode(),addr)
redata = s.recvfrom(1024) #1024表示本次接收的最⼤字节数
print(redata)
s.close()
3.3.3 echo服务器
echo服务器就是发送什么,返回什么
udp接收使用recvfrom方法
from socket import *
s = socket(AF_INET,SOCK_DGRAM)
port = 8888
s.bind(("",port))
rdata = s.recvfrom(1024)
print(rdata)
执行以上代码,程序会等待接受消息
NetAssist端发送消息,程序会接收到如下结果,是一个元组
(b'hehe', ('192.168.34.11', 8080))
结果说明:
b'hehe' #接收到的是一个字节码
192.168.34.11 #发送方IP地址
8080 #发送方端口
以下代码为udp无限接收消息
from socket import *
s = socket(AF_INET,SOCK_DGRAM)
port = 8888
s.bind(("",port)) #绑定8888端口,注意这里是一个元组⚠️
while True:
rdata = s.recvfrom(1024) #s.recvfrom表示接收的消息,1024表示本次接收的最大字节数
s.sendto(rdata[0],rdata[1]) #发送数据,rdata[0]是接受的信息,rdata[1]是接收的IP地址和端口
4.使用socket进行网络通信的过程
1.导入socket模块
2.创建套接字对象
3.绑定IP地址和端口号(接收数据时要绑定端口,发送时可以不绑定)
4.发送消息,需要写明接收方的IP和端口号
5.接受消息(接受消息前如果没有进行过通信,需要先发送一次)
以下代码为模拟全双工,python程序发送信息给NetAssist,NetASssist发送信息给python程序,如果发送的信息中包含886、在见、再见等就退出程序
from socket import *
import time
#1创建套接字
udpSocket = socket(AF_INET, SOCK_DGRAM)
bindAddr = ("",7088)
udpSocket.bind(bindAddr)#绑定
while True:
lst = ['886','在见','再见']
#接收对方发送的数据
recvData = udpSocket.recvfrom(1024)
print(recvData)
print(type(recvData[0].strip())) #类型是字节
print(str(recvData[0].strip(), encoding='gb2312')) #类型是字符串
if str(recvData[0].strip(),encoding='gb2312') in lst:
break
print('[%s] %s.%s' %(time.ctime(),recvData[1],recvData[0].decode("gb2312")))
a = input("请输入:")
udpSocket.sendto(a.encode('gb2312'),('192.168.34.11',8080))
if a in lst:
break
udpSocket.close()
5.udp广播
5.1 概念、分类、示意图
概念
- udp广播:当前网络上所有电脑的某个进程都收到同一个数据(⚠️tcp没有广播)
分类
- 单播:点对点
- 多播:一对多
- 广播:一对所有
示意图
5.2 配置udp广播
发送方
from socket import *
#创建udp套接字
s = socket(AF_INET,SOCK_DGRAM)
#对这个需要发送广播数据的套接字进行修改设置,固定格式,否则不能发送广播数据
s.setsockopt(SOL_SOCKET,SO_BROADCAST,1)
#<broadcast>代表当前网段的广播地址,编码如果不写就是utf-8
s.sendto("udp广播信息测试".encode(),("<broadcast>",8080))
s.close()
接收方
from socket import *
s = socket(AF_INET,SOCK_DGRAM)
addr = s.bind(("",8080))
recv = s.recvfrom(1024)
print(recv[0].decode())
s.close()
运行过程
1.先运行接收方程序等待接受,程序会卡住直到接收到信息
2.发送方运行程序,向当前网络中发送udp广播,接收程序就会收到发送方的信息
6.基于udp实现的TFTP
6.1 TFTP介绍
概念
- TFTP(Trivial File Transfer Protocol,简单文件传输协议)是TCP/IP协议簇中一个用来在客户端和服务器之间进行简单文件传输的协议
作用
- 使用TFTP协议,就可以实现简单文件的下载
特点
- 简单
- 占用资源小
- 适合传递小文件
- 适合在局域网进行传递
- 端口号为69
- 基于udp实现